package monitor

import (
	"fmt"

	"health-check/internal/config"
	"health-check/internal/logger"
	"health-check/internal/notification"
	"health-check/internal/process"
)

// ResourceMonitor 资源监控器
type ResourceMonitor struct {
	config         *config.Config
	processMonitor *process.ProcessMonitor
	notifier       *notification.NotificationManager
}

// NewResourceMonitor 创建资源监控器
func NewResourceMonitor(config *config.Config, processMonitor *process.ProcessMonitor, notifier *notification.NotificationManager) *ResourceMonitor {
	return &ResourceMonitor{
		config:         config,
		processMonitor: processMonitor,
		notifier:       notifier,
	}
}

// CheckResourceLimits 检查资源限制
func (rm *ResourceMonitor) CheckResourceLimits(procConfig config.ProcessConfig, procInfo *process.ProcessInfo) {
	if procConfig.ResourceLimits == nil {
		return
	}

	limits := procConfig.ResourceLimits
	var violations []string

	// 检查CPU使用率
	if limits.MaxCPUPercent > 0 && procInfo.CPU > limits.MaxCPUPercent {
		violations = append(violations, fmt.Sprintf("CPU使用率 %.2f%% 超过限制 %.2f%%",
			procInfo.CPU, limits.MaxCPUPercent))
	}

	// 检查内存使用率
	if limits.MaxMemoryPercent > 0 && procInfo.Memory > limits.MaxMemoryPercent {
		violations = append(violations, fmt.Sprintf("内存使用率 %.2f%% 超过限制 %.2f%%",
			procInfo.Memory, limits.MaxMemoryPercent))
	}

	// 检查内存使用量(MB)
	if limits.MaxMemoryMB > 0 {
		// 这里需要获取实际内存使用量，暂时跳过
		// memoryMB := procInfo.Memory * totalMemory / 100
		// if memoryMB > limits.MaxMemoryMB {
		//     violations = append(violations, fmt.Sprintf("内存使用量 %dMB 超过限制 %dMB",
		//         memoryMB, limits.MaxMemoryMB))
		// }
	}

	// 如果有违规，发送告警
	if len(violations) > 0 {
		message := fmt.Sprintf("进程 %s 资源使用超限:\n%s", procInfo.Name,
			fmt.Sprintf("%s", violations))

		if rm.notifier != nil {
			rm.notifier.SendProcessAlert(procInfo.Name, "resource_limit", message)
		}

		logger.Warnf("进程 %s 资源使用超限: %v", procInfo.Name, violations)
	}
}

// CheckStartupTime 检查启动时间
func (rm *ResourceMonitor) CheckStartupTime(procConfig config.ProcessConfig, procInfo *process.ProcessInfo) {
	// 检查启动时间是否异常（超过30秒认为异常）
	if procInfo.StartupTime > 30000 { // 30秒
		message := fmt.Sprintf("进程 %s 启动时间异常: %dms", procInfo.Name, procInfo.StartupTime)

		if rm.notifier != nil {
			rm.notifier.SendProcessAlert(procInfo.Name, "startup_slow", message)
		}

		logger.Warnf("进程 %s 启动时间异常: %dms", procInfo.Name, procInfo.StartupTime)
	}
}

// ShouldRestartOnExitCode 根据退出码判断是否应该重启
func (rm *ResourceMonitor) ShouldRestartOnExitCode(procConfig config.ProcessConfig, exitCode int) bool {
	if procConfig.ExitCodeConfig == nil {
		return procConfig.AutoRestart // 使用默认配置
	}

	config := procConfig.ExitCodeConfig

	// 检查不需要重启的退出码
	for _, code := range config.NoRestartOnExitCodes {
		if exitCode == code {
			return false
		}
	}

	// 检查需要重启的退出码
	for _, code := range config.RestartOnExitCodes {
		if exitCode == code {
			return true
		}
	}

	// 使用默认配置
	return config.DefaultRestart
}

// GetExitCodeDescription 获取退出码描述
func (rm *ResourceMonitor) GetExitCodeDescription(exitCode int) string {
	descriptions := map[int]string{
		0:   "正常退出",
		1:   "一般错误",
		2:   "误用shell命令",
		126: "命令不可执行",
		127: "命令未找到",
		128: "无效的退出参数",
		130: "通过Ctrl+C终止",
		137: "通过SIGKILL终止",
		143: "通过SIGTERM终止",
	}

	if desc, exists := descriptions[exitCode]; exists {
		return desc
	}

	return fmt.Sprintf("未知退出码: %d", exitCode)
}
